/*************************************************************************
 * TinySG, Copyright (C) 2007, 2008  J.D. Yamokoski
 * All rights reserved.
 * Email: yamokosk at gmail dot com
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the License,
 * or (at your option) any later version. The text of the GNU Lesser General
 * Public License is included with this library in the file LICENSE.TXT.
 *
 * This library is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the file LICENSE.TXT for
 * more details.
 *
 *************************************************************************/
/*
 * Singelton.h
 *
 *  Created on: Jul 23, 2008
 *      Author: yamokosk
 */

#ifndef SINGELTON_H_
#define SINGELTON_H_

#if (_WIN32)
	// Turn off warnings generated by this singleton implementation
#   pragma warning (disable : 4311)
#   pragma warning (disable : 4312)
#endif

#include <assert.h>
#include <tinysg/Exception.h>

namespace TinySG
{

template <typename T> class Singleton
{
public:
	Singleton( void )
	{
		assert( !ms_Singleton );
#if defined( _MSC_VER ) && _MSC_VER < 1200
		int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
		ms_Singleton = (T*)((int)this + offset);
#else
		ms_Singleton = static_cast< T* >( this );
#endif
	}

	~Singleton( void )
	{  assert( ms_Singleton );  ms_Singleton = 0;  }
	static T& getSingleton( void )
	{   assert( ms_Singleton );  return ( *ms_Singleton ); }
	static T* getSingletonPtr( void )
	{ return ms_Singleton; }
protected:
	static T* ms_Singleton;
};

}

#endif /* SINGELTON_H_ */
